package com.rankeiot.core.excel;


import ch.rabanti.nanoxlsx4j.Cell;
import ch.rabanti.nanoxlsx4j.ImportOptions;
import ch.rabanti.nanoxlsx4j.lowLevel.SharedStringsReader;
import ch.rabanti.nanoxlsx4j.lowLevel.StyleReaderContainer;
import ch.rabanti.nanoxlsx4j.lowLevel.WorksheetReader;
import ch.rabanti.nanoxlsx4j.lowLevel.XmlDocument;

import java.io.IOException;
import java.io.InputStream;
import java.util.function.Consumer;

public class WorksheetDataReader extends WorksheetReader {
    private Consumer<Row> rowHandler;
    private Row tempRow=new Row(0,0);
    /**
     * Constructor with parameters and import options
     *
     * @param sharedStrings        SharedStringsReader object
     * @param styleReaderContainer Resolved styles, used to determine dates or times
     * @param options
     */
    public WorksheetDataReader(SharedStringsReader sharedStrings, StyleReaderContainer styleReaderContainer, ImportOptions options) {
        super(sharedStrings, styleReaderContainer, options);
    }
    public void on(Consumer<Row> rowHandler){
        this.rowHandler=rowHandler;
    }
    /**
     * Reads one cell in a worksheet
     *
     * @param rowChild Current child row as XmlNode
     */
    //@Override
    protected void readCell(XmlDocument.XmlNode rowChild) {
        String type = "s";
        String styleNumber = "";
        String address = "A1";
        String value = "";
        if (rowChild.getName().equalsIgnoreCase("c")) {
            address = rowChild.getAttribute("r"); // Mandatory
            type = rowChild.getAttribute("t"); // can be null if not existing
            styleNumber = rowChild.getAttribute("s"); // can be null
            if (rowChild.hasChildNodes()) {
                for (XmlDocument.XmlNode valueNode : rowChild.getChildNodes()) {
                    if (valueNode.getName().equalsIgnoreCase("v")) {
                        value = valueNode.getInnerText();
                    }
                    if (valueNode.getName().equalsIgnoreCase("f")) {
                        value = valueNode.getInnerText();
                    }
                }
            }
        }
        String key = address.toUpperCase();
       // System.out.println(key);
        getStyleAssignment().put(key, styleNumber);
        Cell cell = resolveCellData(value,type,styleNumber,address);
        if(cell.getRowNumber()!=tempRow.getRowNum()){
            rowHandler.accept(tempRow);
            tempRow=new Row(cell.getRowNumber(),0);
            tempRow.addCell(cell);
        }else{
            tempRow.addCell(cell);
        }
        // data.put(key, resolveCellData(value, type, styleNumber, address));
    }
    /**
     * Reads the XML file form the passed stream and processes the worksheet data
     *
     * @param stream Stream of the XML file
     * @throws IOException thrown if the document could not be read
     */
    public void read(InputStream stream) throws IOException {

        try {
            XmlDocument xr = new XmlDocument();
            xr.load(stream);
            XmlDocument.XmlNodeList rows = xr.getDocumentElement().getElementsByTagName("row", true);
            for (int i = 0; i < rows.size(); i++) {
                XmlDocument.XmlNode row = rows.get(i);
//                String rowAttribute = row.getAttribute("r");
//                if (rowAttribute != null) {
//                    String hiddenAttribute = row.getAttribute("hidden");
//                    RowDefinition.addRowDefinition(this.rows, rowAttribute, null, hiddenAttribute);
//                    String heightAttribute = row.getAttribute("ht");
//                    RowDefinition.addRowDefinition(this.rows, rowAttribute, heightAttribute, null);
//                }
                if (row.hasChildNodes()) {
                    for (XmlDocument.XmlNode rowChild : row.getChildNodes()) {
                        readCell(rowChild);
                    }
                }
            }
            rowHandler.accept(tempRow);
        } catch (Exception ex) {
            throw new IOException("The XML entry could not be read from the input stream. Please see the inner exception:", ex);
        } finally {
            if (stream != null) {
                stream.close();
            }
        }
    }

}
